#include <stdio.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>

void print_hex(const char* label, const unsigned char* data, int len) {
    printf("%s: ", label);
    for (int i = 0; i < len; i++) {
        printf("%02x", data[i]);
    }
    printf("\n");
}

int main() {
    AES_KEY encrypt_key, decrypt_key;
    unsigned char key[32] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
                             0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
                             0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
                             0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
    
    unsigned char iv[16] = {0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78,
                            0x87, 0x96, 0xa5, 0xb4, 0xc3, 0xd2, 0xe1, 0xf0};
    
    const char* plaintext = "Hello, AES-CBC encryption!";
    int plaintext_len = strlen(plaintext);
    
    // 确保数据长度是16字节的倍数
    int padded_len = ((plaintext_len + 15) / 16) * 16;
    unsigned char* padded_data = malloc(padded_len);
    memcpy(padded_data, plaintext, plaintext_len);
    
    // PKCS7填充
    int padding = padded_len - plaintext_len;
    for (int i = plaintext_len; i < padded_len; i++) {
        padded_data[i] = padding;
    }
    
    unsigned char encrypted[256] = {0};
    unsigned char decrypted[256] = {0};
    
    // 设置加密密钥
    AES_set_encrypt_key(key, 256, &encrypt_key);
    
    // 设置解密密钥
    AES_set_decrypt_key(key, 256, &decrypt_key);
    
    // 加密
    AES_cbc_encrypt(padded_data, encrypted, padded_len, &encrypt_key, iv, AES_ENCRYPT);
    
    // 重置IV
    unsigned char iv_decrypt[16];
    memcpy(iv_decrypt, iv, 16);
    
    // 解密
    AES_cbc_encrypt(encrypted, decrypted, padded_len, &decrypt_key, iv_decrypt, AES_DECRYPT);
    
    // 移除填充
    int padding_value = decrypted[padded_len - 1];
    if (padding_value > 0 && padding_value <= 16) {
        decrypted[padded_len - padding_value] = '\0';
    } else {
        decrypted[padded_len] = '\0';
    }
    
    printf("Original: %s\n", plaintext);
    print_hex("Encrypted", encrypted, padded_len);
    printf("Decrypted: %s\n", decrypted);
    
    free(padded_data);
    return 0;
}
